﻿using Business.Core.Annotations;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Newtonsoft.Json;
using System.Globalization;
using System.IO;
using Common;
using System.Text.RegularExpressions;
using Microsoft.Extensions.Configuration;
using LinqToDB.Common;
using FangPage.Common;

namespace ProjectManagerSys.backoffice.file
{
    public class KindEditorMerber : Common.BusinessBase
    {
		#region //上传文件
		[Doc("上传文件", Group = "kindEditor文件上传管理")]
        public virtual async Task<dynamic> UpLoadFiles()
        {
            //文件保存目录
            string upLoadPath = System.IO.Path.Combine("/kindEditor", FileHelper.GetDateDir());
            //文件完整目录
            string fullUpLoadPath = System.IO.Path.Combine(FPPath.GetMapPath("/") + upLoadPath);

            //定义允许上传的文件扩展名
            //Hashtable extTable = new Hashtable();
            //extTable.Add("image", "gif,jpg,jpeg,png,bmp");
            //extTable.Add("flash", "swf,flv");
            //extTable.Add("media", "swf,flv,mp3,wav,wma,wmv,mid,avi,mpg,asf,rm,rmvb");
            //extTable.Add("file", "doc,docx,xls,xlsx,ppt,htm,html,txt,zip,rar,gz,bz2");
            string extTable = "gif,jpg,jpeg,png,bmp,doc,docx,xls,xlsx,ppt,htm,html,txt";

            //最大文件大小
            int maxSize = 1000000;
            
            var imgFile = Common.HttpContext.Current.Request.Form.Files["imgFile"];
            if (imgFile == null)
            {
                return (new { error = -1, message = "请选择文件。" });
            }

            String fileName = imgFile.FileName;
            String fileExt = Path.GetExtension(fileName).ToLower();

            if (imgFile == null || imgFile.Length > maxSize)
            {
                return (new { error = -1, message = "上传文件大小超过限制。" });
            }
            //文件扩张名
            
            if (String.IsNullOrEmpty(fileExt) || Array.IndexOf(extTable.Split(','), fileExt.Substring(1).ToLower()) == -1)
            {
                return (new { error = -1, message = "上传文件扩展名是不允许的扩展名。\n只允许" + (extTable) + "格式。"});
            }

            //检查上传的物理路径是否存在，不存在则创建
            if (!Directory.Exists(fullUpLoadPath))
            {
                Directory.CreateDirectory(fullUpLoadPath);
            }

            String newFileName = DateTime.Now.ToString("yyyyMMddHHmmss_ffff", DateTimeFormatInfo.InvariantInfo) + fileExt;
            
            string fullPathName = System.IO.Path.Combine(fullUpLoadPath, newFileName);
            //先存原件，有原件的情况下才能生成缩略图
            using (FileStream fs = System.IO.File.Create(fullPathName))
            {
                imgFile.CopyTo(fs);
                fs.Flush();

            }
            string newFilePath = System.IO.Path.Combine(upLoadPath, newFileName);
			//把实际地址修改为注入的地址
            String fileUrl = newFilePath.Replace(@"\", "/").Replace("kindEditor", "editor");

            Hashtable hash = new Hashtable();
            hash["error"] = 0;
            hash["url"] =fileUrl;
             
            return (JsonConvert.SerializeObject(hash));            
        }

        [Doc("上传文件", Group = "kindEditor文件上传管理")]
        public virtual async Task<dynamic> FileManager()
        {
			
			//String aspxUrl = context.Request.Path.Substring(0, context.Request.Path.LastIndexOf("/") + 1);

			//根目录路径，相对路径
			//String rootPath = "../attached/";
			//根目录URL，可以指定绝对路径，比如 http://www.yoursite.com/attached/
			String rootUrl = System.IO.Path.Combine("/kindEditor", FileHelper.GetDateDir()); ;
			//图片扩展名
			String fileTypes = "gif,jpg,jpeg,png,bmp";

			String currentPath = "";
			String currentUrl = "";
			String currentDirPath = "";
			String moveupDirPath = "";

			string fullUpLoadPath = System.IO.Path.Combine(FPPath.GetMapPath("/") + rootUrl);
			if (!Directory.Exists(fullUpLoadPath))
			{
				Directory.CreateDirectory(fullUpLoadPath);
			}
			//根据path参数，设置各路径和URL
			String path = Common.HttpContext.Current.Request.Query["path"];
			path = String.IsNullOrEmpty(path) ? "" : path;
			if (path == "")
			{
				currentPath = fullUpLoadPath;
				currentUrl = rootUrl;
				currentDirPath = "";
				moveupDirPath = "";
			}
			else
			{
				currentPath = fullUpLoadPath + path;
				currentUrl = rootUrl + path;
				currentDirPath = path;
				moveupDirPath = Regex.Replace(currentDirPath, @"(.*?)[^\/]+\/$", "$1");
			}

			//排序形式，name or size or type
			String order = Common.HttpContext.Current.Request.Query["order"];
			order = String.IsNullOrEmpty(order) ? "" : order.ToLower();

			////不允许使用..移动到上一级目录
			//if (Regex.IsMatch(path, @"\.\."))
			//{
			//	context.Response.Write("Access is not allowed.");
			//	context.Response.End();
			//}
			////最后一个字符不是/
			//if (path != "" && !path.EndsWith("/"))
			//{
			//	context.Response.Write("Parameter is not valid.");
			//	context.Response.End();
			//}
			////目录不存在或不是目录
			//if (!Directory.Exists(currentPath))
			//{
			//	context.Response.Write("Directory does not exist.");
			//	context.Response.End();
			//}

			//遍历目录取得文件信息
			string[] dirList = Directory.GetDirectories(currentPath);
			string[] fileList = Directory.GetFiles(currentPath);

			switch (order)
			{
				case "size":
					Array.Sort(dirList, new NameSorter());
					Array.Sort(fileList, new SizeSorter());
					break;
				case "type":
					Array.Sort(dirList, new NameSorter());
					Array.Sort(fileList, new TypeSorter());
					break;
				case "name":
				default:
					Array.Sort(dirList, new NameSorter());
					Array.Sort(fileList, new NameSorter());
					break;
			}

			Hashtable result = new Hashtable();
			result["moveup_dir_path"] = moveupDirPath;
			result["current_dir_path"] = currentDirPath;
			result["current_url"] = currentUrl;
			result["total_count"] = dirList.Length + fileList.Length;
			List<Hashtable> dirFileList = new List<Hashtable>();
			result["file_list"] = dirFileList;
			for (int i = 0; i < dirList.Length; i++)
			{
				DirectoryInfo dir = new DirectoryInfo(dirList[i]);
				Hashtable hash = new Hashtable();
				hash["is_dir"] = true;
				hash["has_file"] = (dir.GetFileSystemInfos().Length > 0);
				hash["filesize"] = 0;
				hash["is_photo"] = false;
				hash["filetype"] = "";
				hash["filename"] = dir.Name;
				hash["datetime"] = dir.LastWriteTime.ToString("yyyy-MM-dd HH:mm:ss");
				dirFileList.Add(hash);
			}
			for (int i = 0; i < fileList.Length; i++)
			{
				FileInfo file = new FileInfo(fileList[i]);
				Hashtable hash = new Hashtable();
				hash["is_dir"] = false;
				hash["has_file"] = false;
				hash["filesize"] = file.Length;
				hash["is_photo"] = (Array.IndexOf(fileTypes.Split(','), file.Extension.Substring(1).ToLower()) >= 0);
				hash["filetype"] = file.Extension.Substring(1);
				hash["filename"] = file.Name;
				hash["datetime"] = file.LastWriteTime.ToString("yyyy-MM-dd HH:mm:ss");
				dirFileList.Add(hash);
			}
			
			return (JsonConvert.SerializeObject(result));
		}
		#endregion

		public class NameSorter : IComparer
		{
			public int Compare(object x, object y)
			{
				if (x == null && y == null)
				{
					return 0;
				}
				if (x == null)
				{
					return -1;
				}
				if (y == null)
				{
					return 1;
				}
				FileInfo xInfo = new FileInfo(x.ToString());
				FileInfo yInfo = new FileInfo(y.ToString());

				return xInfo.FullName.CompareTo(yInfo.FullName);
			}
		}

		public class SizeSorter : IComparer
		{
			public int Compare(object x, object y)
			{
				if (x == null && y == null)
				{
					return 0;
				}
				if (x == null)
				{
					return -1;
				}
				if (y == null)
				{
					return 1;
				}
				FileInfo xInfo = new FileInfo(x.ToString());
				FileInfo yInfo = new FileInfo(y.ToString());

				return xInfo.Length.CompareTo(yInfo.Length);
			}
		}

		public class TypeSorter : IComparer
		{
			public int Compare(object x, object y)
			{
				if (x == null && y == null)
				{
					return 0;
				}
				if (x == null)
				{
					return -1;
				}
				if (y == null)
				{
					return 1;
				}
				FileInfo xInfo = new FileInfo(x.ToString());
				FileInfo yInfo = new FileInfo(y.ToString());

				return xInfo.Extension.CompareTo(yInfo.Extension);
			}
		}

		public bool IsReusable
		{
			get
			{
				return true;
			}
		}
	}
}
